#include "jsonhandle.h"

#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

#include "log/loghandle.h"

JsonHandle::JsonHandle(QPlainTextEdit *parent):
    w(parent) {}

JsonHandle::~JsonHandle() {}

bool JsonHandle::jsonScan(QString file_name, QString gen_url) {
    QByteArray json_data = getJsonData(file_name);

    if(json_data.isEmpty()) {
        return false;
    }

    file_tree.clear();
    folder_tree.clear();
    file_ctree.clear();
    folder_tree.clear();

    if(!json_data.isEmpty()) {
        QJsonDocument json = jsonParse(json_data);
        jsonErgodic(json, gen_url);

        return true;
    }

    LogHandle(w) << "Json data is empty!";

    return false;
}

QStringList JsonHandle::getFileTree() {
    return file_tree;
}

QStringList JsonHandle::getFolderTree() {
    return folder_tree;
}

QList<CopyTree> JsonHandle::getFileCTree() {
    return file_ctree;
}

QList<CopyTree> JsonHandle::getFolderCTree() {
    return folder_ctree;
}

QByteArray JsonHandle::getJsonData(QString file_name) {
    QByteArray byte_arr;
    QFile file(file_name);

    if(!file.open(QIODevice::ReadOnly)) {
        LogHandle(w) << "Could not find the json file!";
        return QByteArray();
    }

    byte_arr = file.readAll();
    file.close();

    return byte_arr;
}

QJsonDocument JsonHandle::jsonParse(QByteArray json) {
    QJsonParseError json_err;
    QJsonDocument json_doc = QJsonDocument::fromJson(json, &json_err);

    if(json_err.error != QJsonParseError::NoError) {
        LogHandle(w) << json_err.errorString();
        return QJsonDocument();
    }

    return json_doc;
}

void JsonHandle::jsonErgodic(QJsonDocument &json_doc, QString args) {
    if(json_doc.isObject()) {
        QJsonObject json_obj = json_doc.object();
        jsonObjLoop(json_obj, args, args.split('/').size() * 2);
    }
    else {
        LogHandle(w) << "Error json format!";
    }
}

void JsonHandle::jsonObjLoop(QJsonObject &json_obj, QString &args, int deep) {
    deep += 1;
    for(QString &key: json_obj.keys()) {
        QJsonValue json_val = json_obj.value(key);
        jsonValLoop(json_val, key, args, deep);
    }
}

void JsonHandle::jsonArrLoop(QJsonArray &json_arr, QString key, QString &args, int deep) {
    deep += 1;
    for(QJsonArray::iterator i = json_arr.begin();i != json_arr.end(); i ++) {
        QJsonValue json_val = *i;
        jsonValLoop(json_val, key, args, deep);
    }
}

void JsonHandle::jsonValLoop(QJsonValue &json_val, QString key, QString &args, int deep) {
    if(json_val.isObject()) {
        QJsonObject json_obj = json_val.toObject();
        jsonObjLoop(json_obj, args, deep);
    }
    else if(json_val.isArray()) {
        QJsonArray json_arr = json_val.toArray();
        jsonArrLoop(json_arr, key, args, deep);
    }
    else if(json_val.isString()) {
        deep /= 2;
        if(args.split('/').size() > deep) {
            args = args.split('/').mid(0, deep).join('/');
        }

        if(key.compare("name", Qt::CaseInsensitive) == 0) {
            args = QString("%1/%2").arg(args, json_val.toString());
            folder_tree << args;
        }
        else if(key.compare("file", Qt::CaseInsensitive) == 0) {
            args = QString("%1/%2").arg(args, json_val.toString());
            file_tree << args;
        }
        else if(key.compare("demo", Qt::CaseInsensitive) == 0) {
            CopyTree file_cdev;
            file_cdev.from = QString("./%1").arg(json_val.toString());
            file_cdev.to = QString("%1/%2").arg(args, json_val.toString().split('/').last());
            file_ctree << file_cdev;
        }
        else if(key.compare("folder", Qt::CaseInsensitive) == 0) {
            CopyTree folder_cdev;
            folder_cdev.from = QString("./%1").arg(json_val.toString());
            folder_cdev.to = QString("%1/%2").arg(args, json_val.toString().split('/').last());
            folder_ctree << folder_cdev;
        }

//        qDebug() << "Key:" << key << ",String:" << json_val.toString();
//        qDebug() << "args:" << args;
//        qDebug() << "deep:" << deep;
    }
    else if(json_val.isDouble()) {
        LogHandle() << "Key:" << key << ",Double:" << json_val.toString();
    }
    else if(json_val.isBool()) {
        LogHandle() << "Bool:" << json_val.toString();
    }
    else if(json_val.isNull()){
        LogHandle() << "Value is Null!";
    }
    else if(json_val.isUndefined()){
        LogHandle() << "Value is Undefined!";
    }
}
